﻿Imports System.ComponentModel
Imports System.Windows.Forms.Metro.Extensions

Namespace System.Windows.Forms.Metro

    Public Class Form

        Sub New()

            ' Init
            InitializeComponent()

            ' Form Default Style
            Me.Icon = My.Resources.wfm_icon
            Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
            Me.DoubleBuffered = True

            ' Mdi Background color
            If Me.IsMdiChild Then _
                Me.Controls.OfType(Of MdiClient)().All(Function(i)
                                                           i.BackColor = Me.BackColor
                                                           Return True
                                                       End Function)
        End Sub

        Private Sub Form_Load(sender As Object, e As EventArgs) Handles Me.Load
            Me.ToolTipMetro.SetToolTip(Me.ButtonMinimize, Me.ToolStripMenuItemMinimize.Text)
            Me.ToolTipMetro.SetToolTip(Me.ButtonMaximizeRestore,
                                       IIf(Me.WindowState = FormWindowState.Maximized, _
                                           Me.ToolStripMenuItemRestore.Text, _
                                           Me.ToolStripMenuItemMaximize.Text))
            Me.ToolTipMetro.SetToolTip(Me.ButtonClose, Me.ToolStripMenuItemClose.Text)
        End Sub

        'Private _TextReducted As Boolean = False

        Protected Overrides Sub OnPaint(e As PaintEventArgs)
            MyBase.OnPaint(e)

            'ContextMenuStrip Render
            Dim _render As New System.Windows.Forms.Metro.Renderer
            _render.AlterColor = True
            _render.OverrideColor = Me.ForeColor

            With _render.Menustrip

                '.MarginBorder = Me.BorderColor
                '.MarginLeft = Me.BorderColor
                '.MarginRight = Me.BorderColor

                .MenuBorderDark = Me.BorderColor
                .MenuBorderLight = Me.BorderColor

                .BackgroundTop = Me.BackColor
                .BackgroundBottom = Me.BackColor

                .MenustripButtonBorder = Me.BorderColor
                .MenustripButtonBackground = Me.BackColor

                With .Items
                    .InnerBorder = Me.BorderColor
                    .BorderTop = Me.BorderColor
                    .BorderBottom = Me.BorderColor
                    .BorderAngle = 0

                    .HoverBackgroundTop = Me.BorderColor.GetLightColor(92)
                    .HoverBackgroundBottom = Me.BorderColor.GetLightColor(92)
                    
                End With

            End With

            Me.ContextMenuStripForm.Renderer = _render ' ToolStripRenderer(Me)

            'Text title
            'Dim _FinalText As String = Me.Text
            'Dim _Final As System.Drawing.SizeF = e.Graphics.MeasureString(_FinalText, Me.LabelTitle.Font)

            'Do While (_Final.Width) + Me.LabelTitle.Left + (Me.ButtonMinimize.Width * 3) > Me.Width
            '    _FinalText = _FinalText.Substring(0, _FinalText.Length - IIf(_FinalText.EndsWith("..."), 4, 1)) & "..."
            '    _Final = e.Graphics.MeasureString(_FinalText, Me.LabelTitle.Font)
            'Loop

            Me.LabelTitle.Text = Me.Text

            ' Title
            Me.PanelTitle.Visible = Me.ShowTitleBar
            Me.PanelTitle.SendToBack()
            Me.PictureBoxIcon.Image = Me.Icon.ToBitmap
            Me.PictureBoxIcon.Visible = Me.ShowIcon
            'Me.LabelTitle.Left = IIf(Me.ShowIcon, Me.PictureBoxIcon.Left + Me.PictureBoxIcon.Width, Me.PictureBoxIcon.Left)

            ' Tooltip
            Me.ToolTipMetro.BackColor = Me.BackColor
            Me.ToolTipMetro.ForeColor = Me.ForeColor.GetLightColor(92)

            Me.ToolTipMetro.BorderColor = Me.BorderColor
            Me.ToolTipMetro.BorderWidth = Me.BorderWidth / 2

            ' Border paiting
            Me.Padding = New System.Windows.Forms.Padding(Me.BorderWidth)

            If Me.WindowState = FormWindowState.Normal Then
                If Me.Capture = False Then
                    Dim _p As New System.Drawing.Pen(Me.BorderColor, Me.BorderWidth)
                    e.Graphics.DrawRectangle(_p, CInt(Me.BorderWidth / 2), CInt(Me.BorderWidth / 2), Me.Width - Me.BorderWidth, Me.Height - Me.BorderWidth)
                Else
                    Me.Invalidate()
                End If
            End If

            ' Control box
            Me.ButtonMinimize.Visible = Me.MinimizeBox And Me.ControlBox
            Me.ToolStripMenuItemMinimize.Enabled = Me.ButtonMinimize.Visible
            Me.ButtonMaximizeRestore.Visible = Me.MaximizeBox And Me.ControlBox
            Me.ToolStripMenuItemMaximize.Enabled = Me.ButtonMaximizeRestore.Visible And WindowState <> FormWindowState.Maximized
            Me.ToolStripMenuItemRestore.Enabled = Me.ButtonMaximizeRestore.Visible And WindowState = FormWindowState.Maximized
            Me.ButtonClose.Visible = Me.ControlBox
            Me.ToolStripMenuItemClose.Enabled = Me.ButtonClose.Visible

            Me.ButtonMinimize.FlatAppearance.MouseOverBackColor = Me.BorderColor.GetLightColor(92)
            Me.ButtonMaximizeRestore.FlatAppearance.MouseOverBackColor = Me.BorderColor.GetLightColor(92)
            Me.ButtonClose.FlatAppearance.MouseOverBackColor = Me.BorderColor.GetLightColor(92)

            Me.ButtonMinimize.FlatAppearance.MouseDownBackColor = Me.BorderColor.GetLightColor(128)
            Me.ButtonMaximizeRestore.FlatAppearance.MouseDownBackColor = Me.BorderColor.GetLightColor(128)
            Me.ButtonClose.FlatAppearance.MouseDownBackColor = Me.BorderColor.GetLightColor(128)

            Select Case Me.BackColor.GetBrightness
                Case Is >= 0.5
                    Me.ButtonMinimize.Image = My.Resources.minimize_d
                    Me.ButtonMaximizeRestore.Image = IIf(Me.WindowState = FormWindowState.Normal, My.Resources.maximize_d, My.Resources.restore_d)
                    Me.ButtonClose.Image = My.Resources.close_d
                    'Me.PictureBoxSizingGrip.Image = My.Resources.resize_d
                    'Me.ForeColor = System.Drawing.Color.White

                Case Else
                    Me.ButtonMinimize.Image = My.Resources.minimize_d.GetNegativeImage
                    Me.ButtonMaximizeRestore.Image = IIf(Me.WindowState = FormWindowState.Normal, My.Resources.maximize_d.GetNegativeImage, My.Resources.restore_d.GetNegativeImage)
                    Me.ButtonClose.Image = My.Resources.close_d.GetNegativeImage
                    'Me.PictureBoxSizingGrip.Image = My.Resources.resize_l
                    'Me.ForeColor = System.Drawing.Color.Black

            End Select

            Me.ButtonClose.Top = Me.BorderWidth
            Me.ButtonMaximizeRestore.Top = Me.BorderWidth
            Me.ButtonMinimize.Top = Me.BorderWidth

            Me.ButtonClose.Left = Me.Width - Me.ButtonClose.Width - Me.BorderWidth
            Me.ButtonMaximizeRestore.Left = Me.Width - Me.ButtonMaximizeRestore.Width - IIf(Me.ButtonClose.Visible, Me.ButtonClose.Width, 0) - Me.BorderWidth
            Me.ButtonMinimize.Left = Me.Width - Me.ButtonMinimize.Width - IIf(Me.ButtonMaximizeRestore.Visible, Me.ButtonMaximizeRestore.Width, 0) - IIf(Me.ButtonClose.Visible, Me.ButtonClose.Width, 0) - Me.BorderWidth

            'Me.PictureBoxSizingGrip.Left = Me.Width - Me.BorderWidth - Me.PictureBoxSizingGrip.Width - Me.PictureBoxSizingGrip.Margin.Right - Me.PictureBoxSizingGrip.Margin.Left
            'Me.PictureBoxSizingGrip.Top = Me.Height - Me.BorderWidth - Me.PictureBoxSizingGrip.Height - Me.PictureBoxSizingGrip.Margin.Bottom - Me.PictureBoxSizingGrip.Margin.Top

        End Sub

#Region " ShowDialog "

        Private _IsDialog As Boolean
        Public ReadOnly Property IsDialog As Boolean
            Get
                Return _IsDialog
            End Get
        End Property
        Public Overloads Function ShowDialog() As DialogResult
            _IsDialog = True
            Return MyBase.ShowDialog
        End Function

#End Region

#Region " Shadow "

        Private Const CS_DROPSHADOW As Integer = 131072
        Protected Overrides ReadOnly Property CreateParams As System.Windows.Forms.CreateParams
            Get
                If Not Me.DesignMode Then
                    Dim cp As CreateParams = MyBase.CreateParams
                    cp.ClassStyle = cp.ClassStyle Or CS_DROPSHADOW
                    Return cp
                Else
                    Return MyBase.CreateParams
                End If
            End Get
        End Property

#End Region

#Region " Properties "

#Region " Border "

        Private _BorderColor As System.Drawing.Color = System.Drawing.Color.Gray
        <DefaultValue("System.Drawing.Color.Gray")> _
        <Category("Border")> _
        Public Property BorderColor As System.Drawing.Color
            Get
                Return _BorderColor
            End Get
            Set(value As System.Drawing.Color)
                If _BorderColor <> value Then
                    _BorderColor = value
                    Me.Invalidate()
                End If
            End Set
        End Property

        Private _BorderWidth As Integer = 2
        <DefaultValue(2)> _
        <Category("Border")> _
        Public Property BorderWidth As Integer
            Get
                Return _BorderWidth
            End Get
            Set(value As Integer)
                If _BorderWidth <> value Then
                    _BorderWidth = value
                    Me.Invalidate()
                End If
            End Set
        End Property

#End Region

#Region " StatusBar "

        Private _SizingGrip As Boolean = True
        <DefaultValue(True)> _
        Public Property SizingGrip As Boolean
            Get
                Return _SizingGrip
            End Get
            Set(value As Boolean)
                If _SizingGrip <> value Then
                    _SizingGrip = value
                    Me.Invalidate()
                End If
            End Set
        End Property

        Private _ShowStatusBar As Boolean = True
        <DefaultValue(True)> _
        Public Property ShowStatusBar() As Boolean
            Get
                Return _ShowStatusBar
            End Get
            Set(ByVal value As Boolean)
                If _ShowStatusBar <> value Then
                    _ShowStatusBar = value
                    Me.Invalidate()
                End If
            End Set
        End Property

#End Region

#Region " Title Bar "

        Private _ShowTitleBar As Boolean = True
        <DefaultValue(True)> _
        Public Property ShowTitleBar() As Boolean
            Get
                Return _ShowTitleBar
            End Get
            Set(ByVal value As Boolean)
                If _ShowTitleBar <> value Then
                    _ShowTitleBar = value
                    Me.Invalidate()
                End If
            End Set
        End Property

#End Region

#End Region

#Region " Form moving "

        Private Const WM_SYSCOMMAND As Integer = &H112&
        Private Const MOUSE_MOVE As Integer = &HF012&

        <System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint:="ReleaseCapture")> _
        Private Shared Sub ReleaseCapture()
        End Sub

        <System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint:="SendMessage")> _
        Private Shared Sub SendMessage(ByVal hWnd As System.IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer)
        End Sub

        Private Sub MoveForm()
            ReleaseCapture()
            SendMessage(Me.Handle, WM_SYSCOMMAND, MOUSE_MOVE, 0)
        End Sub

        Private _Size As System.Drawing.Size

        Private Sub Form_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove, LabelTitle.MouseMove
            If e.Button = Windows.Forms.MouseButtons.Left Then

                If _Size <> Nothing Then
                    Me.Size = _Size
                    _Size = Nothing
                End If

                MoveForm()

                If Me.MaximizeBox Then
                    If Me.Left <= 0 Then
                        If Me.Size <> New System.Drawing.Size((My.Computer.Screen.WorkingArea.Width / 2), My.Computer.Screen.WorkingArea.Height) And _
                            Me.Location <> New System.Drawing.Point(0, 0) Then
                            _Size = Me.Size
                            Me.Size = New System.Drawing.Size((My.Computer.Screen.WorkingArea.Width / 2), My.Computer.Screen.WorkingArea.Height)
                            Me.Location = New System.Drawing.Point(0, 0)
                        End If
                    ElseIf (Me.Left + e.Location.X) >= (My.Computer.Screen.WorkingArea.Width - 16) Then ' - e.Location.X) - 100 Then
                        If Me.Size <> New System.Drawing.Size(My.Computer.Screen.WorkingArea.Width / 2, My.Computer.Screen.WorkingArea.Height) And _
                          Me.Location <> New System.Drawing.Point((My.Computer.Screen.WorkingArea.Width - Me.Width), 0) Then
                            _Size = Me.Size
                            Me.Size = New System.Drawing.Size((My.Computer.Screen.WorkingArea.Width / 2), My.Computer.Screen.WorkingArea.Height)
                            Me.Location = New System.Drawing.Point((My.Computer.Screen.WorkingArea.Width - Me.Width), 0)
                        End If
                    ElseIf Me.Top <= 0 Then
                        'Me.ButtonMaximizeRestore.PerformClick()
                        Me.WindowState = FormWindowState.Maximized
                    End If
                End If
            Else
                Me.Cursor = Cursors.[Default]
            End If
        End Sub

#End Region

#Region " Control box "

        Public Event CloseClick As EventHandler
        Public Event MaximizeClick As EventHandler
        Public Event RestoreClick As EventHandler
        Public Event MinimizeClick As EventHandler

        Friend Overridable Sub OnMinimize_Click(sender As Object, e As EventArgs) Handles ButtonMinimize.Click, ToolStripMenuItemMinimize.Click
            Me.WindowState = FormWindowState.Minimized
            RaiseEvent MinimizeClick(Me, e)
        End Sub
        Friend Overridable Sub OnMaximizeClick(sender As Object, e As EventArgs) Handles ButtonMaximizeRestore.Click, ToolStripMenuItemMaximize.Click
            If Me.WindowState = FormWindowState.Normal Then
                Me.WindowState = FormWindowState.Maximized
                Me.ToolTipMetro.SetToolTip(Me.ButtonMaximizeRestore, Me.ToolStripMenuItemRestore.Text)
                RaiseEvent MaximizeClick(Me, e)
            Else
                Me.WindowState = FormWindowState.Normal
                Me.ToolTipMetro.SetToolTip(Me.ButtonMaximizeRestore, Me.ToolStripMenuItemMaximize.Text)
                RaiseEvent RestoreClick(Me, e)
            End If
        End Sub
        Friend Overridable Sub OnRestoreClick(sender As Object, e As EventArgs) Handles ToolStripMenuItemRestore.Click 'Handles ButtonMaximizeRestore.Click
            OnMaximizeClick(sender, e)
        End Sub
        Friend Overridable Sub OnCloseClick(sender As Object, e As EventArgs) Handles ButtonClose.Click, ToolStripMenuItemClose.Click
            RaiseEvent CloseClick(Me, e)
            Me.Close()
        End Sub

        Friend Overridable Sub OnControlButtonEnter(sender As Object, e As EventArgs) Handles ButtonMinimize.MouseEnter, ButtonMaximizeRestore.MouseEnter, ButtonClose.MouseEnter
            With CType(sender, System.Windows.Forms.Button)
                .Tag = .Image
                .Image = .Image.GetColorMask(Me.BorderColor.GetDarkColor(64))
            End With
        End Sub
        Friend Overridable Sub OnControlButtonLeave(sender As Object, e As EventArgs) Handles ButtonMinimize.MouseLeave, ButtonMaximizeRestore.MouseLeave, ButtonClose.MouseLeave
            With CType(sender, System.Windows.Forms.Button)
                .Image = .Tag
                .Tag = Nothing
            End With
        End Sub

        Private Sub OnControlButtonDown(sender As Object, e As MouseEventArgs) Handles ButtonMinimize.MouseDown, ButtonMaximizeRestore.MouseDown, ButtonClose.MouseDown
            With CType(sender, System.Windows.Forms.Button)
                .Image = CType(.Tag, System.Drawing.Image).GetColorMask(Me.BorderColor)
            End With
        End Sub

#End Region

        Private Sub Form_Click(sender As Object, e As MouseEventArgs) Handles PictureBoxIcon.MouseClick, Me.MouseClick, LabelTitle.MouseClick
            If sender Is PictureBoxIcon Then
                If e.Button = Windows.Forms.MouseButtons.Left Then _
                PictureBoxIcon.ContextMenuStrip.Show(PictureBoxIcon, PictureBoxIcon.Location)
            Else
                If e.Button = Windows.Forms.MouseButtons.Right Then
                    Dim _rect As New System.Drawing.Rectangle(0, 0, Me.Width, Me.PictureBoxIcon.Height + Me.PictureBoxIcon.Top)
                    If _rect.Contains(e.X, e.Y) Then
                        PictureBoxIcon.ContextMenuStrip.Show(sender, e.Location)
                    End If
                End If
            End If
        End Sub

        Private Sub Form_DoubleClick(sender As Object, e As MouseEventArgs) Handles LabelTitle.MouseDoubleClick
            Dim _rect As New System.Drawing.Rectangle(0, 0, Me.Width, Me.PictureBoxIcon.Height + Me.PictureBoxIcon.Top)
            If _rect.Contains(e.X, e.Y) Then
                Me.ButtonMaximizeRestore.PerformClick()
            End If

        End Sub

#Region " StatusStrip Mouse "

        'Private Const WM_NCLBUTTONDOWN As Integer = &HA1S
        'Private Const HTBOTTOMRIGHT As Integer = 17

        'Private Sub StatusStripMetro_MouseDown(sender As Object, e As MouseEventArgs) Handles StatusStripMetro.MouseDown
        '    If Me.WindowState <> FormWindowState.Maximized Then
        '        If e.Button = Windows.Forms.MouseButtons.Left Then
        '            Me.Capture = False

        '            Dim theCursor As Cursor = Cursors.Arrow
        '            Dim Direction As New IntPtr(Bottom)

        '            If e.X = StatusStripMetro.Width - 1 Or e.X = StatusStripMetro.Width - 2 Or e.X = StatusStripMetro.Width - 3 Or e.X = StatusStripMetro.Width - 4 Or e.X = StatusStripMetro.Width - 5 _
        '                Or e.Y = StatusStripMetro.Height - 1 Or e.Y = StatusStripMetro.Height - 2 Or e.Y = StatusStripMetro.Height - 3 Or e.Y = StatusStripMetro.Height - 4 Or e.Y = StatusStripMetro.Height - 5 Then
        '                Select Case e.X
        '                    Case StatusStripMetro.Width - 5 To StatusStripMetro.Width - 1
        '                        Select Case e.Y
        '                            Case StatusStripMetro.Height - 5 To StatusStripMetro.Height - 1
        '                                Direction = CType(HTBOTTOMRIGHT, IntPtr)
        '                                theCursor = Cursors.SizeNWSE
        '                        End Select
        '                End Select
        '                Me.Cursor = theCursor
        '                Dim msg As Message = _
        '                        Message.Create(Me.Handle, WM_NCLBUTTONDOWN, _
        '                            Direction, IntPtr.Zero)
        '                Me.DefWndProc(msg)

        '            End If
        '        End If
        '    End If
        'End Sub
        'Private Sub StatusStripMetro_MouseMove(sender As Object, e As MouseEventArgs) Handles StatusStripMetro.MouseMove
        '    If Me.WindowState <> FormWindowState.Maximized Then
        '        If e.X = StatusStripMetro.Width - 1 Or e.X = StatusStripMetro.Width - 2 Or e.X = StatusStripMetro.Width - 3 Or e.X = StatusStripMetro.Width - 4 Or e.X = StatusStripMetro.Width - 5 _
        '        Or e.Y = StatusStripMetro.Height - 1 Or e.Y = StatusStripMetro.Height - 2 Or e.Y = StatusStripMetro.Height - 3 Or e.Y = StatusStripMetro.Height - 4 Or e.Y = StatusStripMetro.Height - 5 Then
        '            Dim theCursor As Cursor = Cursors.Arrow
        '            Select Case e.X
        '                Case StatusStripMetro.Width - 5 To StatusStripMetro.Width - 1
        '                    Select Case e.Y
        '                        Case StatusStripMetro.Height - 5 To StatusStripMetro.Height - 1
        '                            theCursor = Cursors.SizeNWSE
        '                            'If e.Button = Windows.Forms.MouseButtons.Left Then
        '                            '    'Me.ARNG_WINDOW(Me.Size)
        '                            'End If
        '                            Me.Invalidate()
        '                    End Select
        '            End Select
        '            Me.Cursor = theCursor
        '        End If
        '    End If
        'End Sub
        'Private Sub StatusStripMetro_MouseUp(sender As Object, e As MouseEventArgs) Handles StatusStripMetro.MouseUp
        '    If StatusStripMetro.SizeGripBounds.Contains(e.Location) Then
        '        Me.Cursor = Cursors.SizeNWSE
        '    End If
        'End Sub
        Private Sub Form_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            Me.Invalidate()
        End Sub

#End Region

       
        
    End Class

End Namespace